<template>
  <div class="ddio-websocket">
    <el-tooltip
      class="item"
      effect="dark"
      :content="$t('websocket.viewDetails')"
      placement="left"
    >
      <div
        :class="{ 'ddio-box': true, 'ddio-move': animateState }"
        @click="goMyMessage"
      >
        <span>{{ redata }}</span>
        <svg-icon icon-class="small-bell" />
      </div>
    </el-tooltip>
  </div>
</template>

<script>
import { mapGetters } from 'vuex';
import * as websocket from '@/api/websocket';

export default {
  name: 'DdioWebsocket',
  data() {
    return {
      animateState: false,
      websock: null,
      redata: 0,
      reconnectLock: false,
      reconnectTimer: null,
      reconnectInterval: 3000,
      reconnectLimitCounts: 10,
      reconnectedCounts: 0,
      heartTimeout: 30000,
      heartTimer: null,
      heartServerTimer: null,
      heartCheckMsg: { status: 'client is ok' },
    };
  },
  computed: {
    ...mapGetters(['id']),
  },
  created() {
    this.initWebSocket();
  },
  destroyed() {
    // 离开路由之后断开websocket连接
    this.websock.close();
  },
  methods: {
    /**
     * 初始化weosocket
     */
    initWebSocket() {
      this.websock = new WebSocket(websocket.ddioWebsocket(this.id));
      this.websock.onmessage = this.websocketonmessage;
      this.websock.onopen = this.websocketonopen;
      this.websock.onerror = this.websocketonerror;
      this.websock.onclose = this.websocketclose;
      this.reconnectLock = false;
    },
    /**
     * 连接建立之后执行send方法发送数据
     */
    websocketonopen() {
      this.heartCheck();
    },
    /**
     * 连接建立失败重连
     */
    websocketonerror() {
      this.reconnect();
    },
    /**
     * 数据接收
     */
    websocketonmessage(e) {
      if (isNaN(e.data)) {
        return;
      }
      this.redata = e.data;
      // 执行消息铃铛左右摇晃动画
      this.animateTrigger();
      this.heartCheck();
    },
    /**
     * 数据发送
     */
    websocketsend(Data) {
      this.websock.send(Data);
    },
    /**
     * 关闭
     */
    websocketclose(e) {
      this.reconnect();
    },
    /**
     * 重连
     */
    reconnect() {
      if (
        this.reconnectLock ||
        this.reconnectedCounts > this.reconnectLimitCounts - 1
      ) {
        return;
      }
      this.reconnectedCounts++;
      this.reconnectLock = true;
      if (this.reconnectTimer) {
        clearTimeout(this.reconnectTimer);
      }
      this.reconnectTimer = setTimeout(
        this.initWebSocket,
        this.reconnectInterval
      );
    },
    /**
     * 断开重连
     */
    resetReconnect() {
      this.reconnectedCounts = 0;
      this.reconnectLock = false;
      this.reconnect();
    },
    /**
     * 心跳检测
     */
    heartCheck() {
      // 如果需要心跳检查，释放注释即可
      // this.heartTimer && clearTimeout(this.heartTimer);
      // this.heartServerTimer && clearTimeout(this.heartServerTimer);
      // this.heartTimer = setTimeout(() => {
      //   this.websocketsend(JSON.stringify(this.heartCheckMsg));
      //   this.heartServerTimer = setTimeout(
      //     this.resetReconnect,
      //     this.heartTimeout
      //   );
      // }, this.heartTimeout);
    },
    /**
     * 跳转到我的消息路由页面
     */
    goMyMessage() {
      this.$router.push({ name: 'myMessage' });
    },
    /**
     * 消息铃铛动画
     */
    animateTrigger() {
      this.animateState = true;
      setTimeout(() => {
        this.animateState = false;
      }, 2000);
    },
  },
};
</script>

<style scoped lang="scss">
.ddio-websocket {
  position: relative;
  display: inline-block;
  vertical-align: top;
  margin-right: 5px;
  font-size: 20px;
  color: #409eff;
  cursor: pointer;
  .ddio-box {
    position: relative;
    span {
      position: absolute;
      top: 8px;
      left: 10px;
      height: 18px;
      padding: 0 3px;
      line-height: 18px;
      font-size: 12px;
      font-weight: bold;
      color: #ffffff;
      background-color: #f56c6c;
      border-radius: 5px;
      transform: scale(0.75, 0.75);
    }
  }
}
@keyframes move {
  10% {
    transform: rotate(15deg);
  }
  20% {
    transform: rotate(-10deg);
  }
  30% {
    transform: rotate(5deg);
  }
  40% {
    transform: rotate(-5deg);
  }
  50%,
  100% {
    transform: rotate(0deg);
  }
}
.ddio-move {
  animation: move 2s 0s infinite;
  transform-origin: top;
}
</style>
